<script setup>
import {ref,onMounted,reactive,nextTick} from 'vue'
// import {reqUserInfo,reqAddOrUpdateUser,reqAllRole,reqGetUserRole,reqSetUserRole,reqRemoveUser,reqBatchRemoveUser} from '@/api/acl/user'
import {reqUserInfo,reqAddOrUpdateUser,reqAllRole,reqSetUserRole,reqRemoveUser,reqBatchRemoveUser} from '@/api/acl/user'
import {ElMessage} from 'element-plus'
import useLayoutSettingStore from '@/store/setting'

let pageNo = ref(1)  // 保存当前页
let pageSize = ref(10)  // 保存每页数量
let total = ref(100)  // 保存数据总数
let userArr = ref([])  // 保存用户列表

let drawer = ref(false)  // 设置抽屉组件的显示与隐藏
let drawer1 = ref(false)  // 设置 分配角色抽屉组件 的显示与隐藏
let userParams = reactive({  // 保存新的用户数据
    id:0,
    username:'',
    nick_name:'',
    password:'',
    password2:'',
})

let formRef=ref()  // 获取form组件实例，后面验证用户输入的信息时要用到

let checkAll = ref(false)  // 保存复选框 全选/全不选 的值
let isIndeterminate = ref(true)  // 设置不确定状态
let allRole = ref([])  // 角色列表
let userRole = ref([])  // 保存用户的角色

let selectUserArr = ref([]) // 保存要批量删除的用户

let keyword = ref('')  // 保存用户输入的搜索关键字

let settingStore = useLayoutSettingStore()  // 控制刷新的仓库

// 获取用户列表
const getAllUser = (page=1)=>{
    pageNo.value = page
    reqUserInfo(pageNo.value,pageSize.value,keyword.value).then(res=>{
        if(res.data.code==200){
            total.value = res.data.data.total_num
            userArr.value = res.data.data.user_list
        }
    })
}
// 获取所有的角色信息
const getAllRole = ()=>{
    reqAllRole().then(res=>{
        if(res.data.code==200){
            allRole.value=res.data.data
        }
    })
}

onMounted(()=>{
    getAllUser()  // 页面加载后，获取用户列表
    getAllRole()  // 获取所有的角色信息
})

// pageSize发生改变时调用
const handler = (pageSize)=>{
    getAllUser()
}

// 点击添加用户按钮触发事件
const addUser=()=>{
    drawer.value=true
    // 清空之前的数据，这个要分两步，先清空数据，再清空错误信息
    Object.assign(userParams,{
        id:0,
        username:'',
        nick_name:'',
        password:'',
        password2:'',
    })
    // 清空之前的错误信息
    nextTick(()=>{
        formRef.value.clearValidate('username')
        formRef.value.clearValidate('nick_name')
        formRef.value.clearValidate('password')
        formRef.value.clearValidate('password2')
    })
    // 还可以用这种方式来判断值是否存在，如果存在才执行后面的操作
    // formRef.value?.clearValidate('username')

    // formRef.value.resetFields()可以清空表单的一些数据，但有些问题。有时间可以尝试一下
    // nextTick(()=>{
    //     userParams.id=0  // 手动清空id
    //     formRef.value.resetFields()
    // })
}
// 点击编辑用户按钮触发事件
const updateUser = (row)=>{
    // row为当前 el-table-column中的信息
    drawer.value=true
    nextTick(()=>{
        formRef.value.clearValidate('username')
        formRef.value.clearValidate('nick_name')
    })
    
    // 获取用户的原始信息
    Object.assign(userParams,row)
}
// 点击确定按钮触发事件
const save = async ()=>{
    //添加或者更新用户
    // userParams.id=10
    
    // 校验用户输入的信息，如果通过会返回一个成功的promise，程序往下执行，如果不通过会返回一个失败的promise，程序不会往下执行
    await formRef.value.validate()

    reqAddOrUpdateUser(userParams).then(res=>{
        if(res.data.code==200){
            ElMessage({
                type:'success',
                message:userParams.id ? '更新成功':'添加成功'
            })
            getAllUser(userParams.id?pageNo.value:1)
            drawer.value=false
            // window.location.reload()  // 浏览器刷新
        }else{
            ElMessage({
                type:'error',
                message:userParams.id ? '更新失败，'+res.data.msg:'添加失败，'+res.data.msg
            })
        }
    })
}
// 点击取消按钮触发事件
const cancel = ()=>{
    drawer.value=false
}

// 自定义表单校验规则
// 校验用户名的方法
const validatorUsername = (rule,value,callBack)=>{
    // 参数说明：rule是规则，value是传进来的值，callBack是回调函数
    // 用户名只能以5-20位字母数字_@-组成，且必须以字母或者下划线_开头
    if( /^[a-zA-Z_][a-zA-Z0-9_\-@]{4,19}$/.test(value) ){
        // 符合条件则正常调用callBack方法
        callBack()
    }else{
        // 不符合条件，返回一个错误信息
        callBack(new Error('用户名只能以5-20位字母数字下划线@-组成，且必须以字母或者下划线_开头'))
    }
}
// 校验昵称的方法
const validatorNickName = (rule,value,callBack)=>{
    // 昵称以5-20位字母数字中文下划线@-#组成
    if( !value | /^[a-zA-Z0-9_\-@\u4e00-\u9fa5、，。；：？！……「」《》【】〖〗『』()“”‘’\.]{5,20}$/.test(value) ){
        callBack()  // 符合条件，正常调用callBack
    }else{
        // 不符合条件，返回一个错误信息
        callBack(new Error('昵称以5-20位字母数字中文下划线@-#组成'))
    }
}
// 校验密码的方法
const validatorPassword = (rule,value,callBack)=>{
    // 密码以5-20位字母数字下划线@-#组成
    if( /^[a-zA-Z0-9_\-@]{5,20}$/.test(value) ){
        callBack()  // 符合条件，正常调用callBack
    }else{
        // 不符合条件，返回一个错误信息
        callBack(new Error('密码以5-20位字母数字下划线@-#组成'))
    }
}
// 校验确认密码的方法
const validatorPassword2 = (rule,value,callBack)=>{
    // 两次输入的密码需相同
    if( userParams.password==userParams.password2 ){
        callBack()  // 符合条件，正常调用callBack
    }else{
        // 不符合条件，返回一个错误信息
        callBack(new Error('两次密码需相同'))
    }
}
// 自定义表单校验规则
const rules = {
    // 用户名
    username:[{required:true, trigger:'blur', validator:validatorUsername}],
    nick_name:[{trigger:'blur', validator:validatorNickName}],
    password:[{required:true, trigger:'blur', validator:validatorPassword}],
    password2:[{required:true, trigger:'blur', validator:validatorPassword2}],
}

// 点击分配角色按钮触发事件
const setRole = (row)=>{
    // 显示抽屉组件
    drawer1.value = true
    // 保存已有的信息
    Object.assign(userParams,row)
    userRole.value = row.role.map(item => {
        return item
    })
    // 更改复选框状态
    handleCheckedCitiesChange(userRole.value)
    // 获取用户的角色列表
    // reqGetUserRole(row.id).then(res=>{
    //     if(res.data.code==200){
    //         // console.log(res.data.data);
    //         userRole.value = res.data.data.map(item => {
    //             return item.name
    //         })
    //         // 更改复选框状态
    //         handleCheckedCitiesChange(userRole.value)
    //     }else{
    //         ElMessage({
    //             type:'error',
    //             message:'获取用户角色失败，' + res.data.msg
    //         })
    //     }
    // })
}
// 全选复选框触发的事件
const handleCheckAllChange = (val) =>{
    userRole.value = val?allRole.value:[]
    isIndeterminate.value = false
}
// 多选框选项发生改变时触发事件
const handleCheckedCitiesChange = (value) => {
    // let checkedCount = value.length
    // isIndeterminate.value = !(checkedCount === allRole.value.length | userRole.value.length==0 )
    // checkAll.value = checkedCount === allRole.value.length
    
    let checkedCount = value.length  // value是当前选择的列表项
    checkAll.value = checkedCount === allRole.value.length  // 判断是否全选
    isIndeterminate.value = checkedCount > 0 && checkedCount < allRole.value.length  // 判断是否在中间状态
}
// 分配角色页面 点击取消按钮触发事件
const cancel1 = ()=>{
    drawer1.value = false
}
// 分配角色页面，点击确定按钮触发事件
const confirmClick = ()=>{
    let data = {
        userId:userParams.id,
        roleIdList:userRole.value.map(item=> item.id)
    }
    reqSetUserRole(data).then(res=>{
        if(res.data.code==200){
            ElMessage({
                type:'success',
                message:'设置成功'
            })
            getAllUser(pageNo.value)
            drawer1.value=false
        }else{
            ElMessage({
                type:'success',
                message:'设置失败，'+res.data.msg
            })
        }
    })
    
}
// 点击删除按钮，删除单个用户
const deleteUser = (row)=>{
    // reqBatchRemoveUser(row.id).then(res=>{
    //     console.log(res.data);
    // })
    reqRemoveUser(row.id).then(res=>{
        if(res.data.code==200){
            ElMessage({
                type:'success',
                message:'删除成功'
            })
            getAllUser(userArr.value.length>1 ? pageNo.value : pageNo.value-1)
        }else{
            ElMessage({
                type:'error',
                message:'删除失败，' + res.data.msg
            })
        }
    })
}

// el-table组件选择项发生变化时触发的事件
const selectChange = (value)=>{
    selectUserArr.value = value
}
// 点击批量删除按钮，删除多个用户
const batchRemoveUser = ()=>{
    let userIdArr = selectUserArr.value.map(item=>item.id)
    reqBatchRemoveUser(userIdArr).then(res=>{
        if(res.data.code==200){
            ElMessage({
                type:'success',
                message:'删除成功'
            })
            
            let current_user_count = userArr.value.length-userIdArr.length
            getAllUser(current_user_count >1 ? pageNo.value : pageNo.value-1)
        }else{
            ElMessage({
                type:'error',
                message:'删除失败，' + res.data.msg
            })
        }
    })
}

// 点击搜索按钮触发的事件
const search = ()=>{
    getAllUser()
}
// 点击重置按钮触发事件
const reset = ()=>{
    settingStore.refsh = !settingStore.refsh
}

</script>

<template>
    <div class="box">
        <el-card style="height: 80px;">
            <el-form :inline="true" class="form">
                <el-form-item label="用户名">
                    <el-input placeholder="请输入用户名" v-model="keyword"></el-input>
                </el-form-item>
                <el-form-item >
                    <el-button type="primary" :disabled="keyword?false:true" @click="search">搜索</el-button>
                    <el-button type="primary" @click="reset">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>
        <el-card style="margin: 10px 0;">
            <el-button v-has="`btn.User.add`" type="primary" @click="addUser">添加用户</el-button>
            <el-popconfirm :title="`你确定要删除这些用户吗？`" width="260px" @confirm="batchRemoveUser">
                <template #reference>
                    <el-button v-has="`btn.User.batchDelete`" type="primary" :disabled="selectUserArr.length<1 ? true:false">批量删除</el-button>
                </template>
            </el-popconfirm>
            
            
            <!-- el-table展示用户信息 -->
            <el-table style="margin: 10px 0;" border :data="userArr" @selection-change="selectChange">
                <el-table-column type="selection" align="center"></el-table-column>
                <el-table-column label="#" type="index" width="80px" align="center"></el-table-column>
                <el-table-column label="ID" width="80px" align="center" prop="id"></el-table-column>
                <el-table-column label="用户名" align="center" prop="username" show-overflow-tooltip></el-table-column>
                <el-table-column label="用户昵称" align="center" prop="nick_name" show-overflow-tooltip></el-table-column>
                <el-table-column label="用户角色" align="center" prop="role" show-overflow-tooltip>
                    <template #="{row,$index}">
                        <span style="color: chocolate;"> {{ row.role.map(item=>{return item.name}).join(',') }}</span>
                        <!-- <span v-for="(item,index) in row.role" style="color: chocolate;">【{{ item.name }}】 </span> -->
                    </template>
                </el-table-column>
                <el-table-column label="创建时间" align="center" prop="create_time" show-overflow-tooltip></el-table-column>
                <el-table-column label="更新时间" align="center" prop="update_time" show-overflow-tooltip></el-table-column>
                <el-table-column label="操作" width="280px" fixed="right">
                    <template #="{row,$index}">
                        <el-button v-has="`btn.User.setRole`" type="primary" size="small" icon="User" @click="setRole(row)">分配角色</el-button>
                        <el-button v-has="`btn.User.edit`" type="primary" size="small" icon="Edit" @click="updateUser(row)">编辑</el-button>
                        <el-popconfirm :title="`你确定要删除 ${row.username} 吗？`" width="260px" @confirm="deleteUser(row)">
                            <template #reference>
                                <el-button v-has="`btn.User.delete`" type="primary" size="small" icon="Delete">删除</el-button>
                            </template>
                        </el-popconfirm>
                        
                    </template>
                </el-table-column>
            </el-table>

            <!-- 分页器 -->
            <el-pagination
                v-model:current-page="pageNo"
                v-model:page-size="pageSize"
                :page-sizes="[10, 20, 30, 50]"
                background
                layout="prev, pager, next, jumper,total, sizes"
                :total="total"
                @current-change="getAllUser"
                @size-change="handler"
                />


            <!-- 抽屉组件 -->
            <el-drawer v-model="drawer" direction="rtl" >
                <template #header>
                    <h4>{{ userParams.id?'编辑用户':'添加用户' }}</h4>
                </template>
                <template #default>
                    <el-form label-width="80px" label-position="right" :model="userParams" :rules="rules" inline-message ref='formRef'>
                        <el-form-item label="用户名" prop="username">
                            <el-input placeholder="请输入用户名" v-model="userParams.username"></el-input>
                        </el-form-item>
                        <el-form-item label="用户昵称" prop="nick_name">
                            <el-input placeholder="请输入用户昵称" v-model="userParams.nick_name"></el-input>
                        </el-form-item>
                        <el-form-item label="密码" prop="password" v-if="!userParams.id">
                            <el-input placeholder="请输入用户密码" type="password" v-model="userParams.password"></el-input>
                        </el-form-item>
                        <el-form-item label="确认密码" prop="password2" v-if="!userParams.id">
                            <el-input placeholder="再次输入用户密码" type="password" v-model="userParams.password2"></el-input>
                        </el-form-item>
                    </el-form>
                    
                </template>
                <template #footer>
                    <div>
                        <el-button @click="cancel">取消</el-button>
                        <el-button type="primary" @click="save">确定</el-button>
                    </div>
                </template>
            </el-drawer>

            <!-- 抽屉组件,分配角色 -->
            <el-drawer v-model="drawer1" direction="rtl" >
                <template #header>
                    <h4>分配角色</h4>
                </template>
                <template #default>
                    <el-form label-width="80px" label-position="right" >
                        <el-form-item label="用户名">
                            <el-input placeholder="请输入用户名" v-model="userParams.username" :disabled="true"></el-input>
                        </el-form-item>
                        <el-form-item label="角色列表">
                            <el-checkbox
                                v-model="checkAll"
                                :indeterminate="isIndeterminate"
                                @change="handleCheckAllChange"
                                >全选</el-checkbox
                            >
                            <el-checkbox-group v-model="userRole" @change="handleCheckedCitiesChange" >
                                <el-checkbox v-for="(role,index) in allRole" :key="index" :label="role">{{ role.name }}</el-checkbox>
                            </el-checkbox-group>
                        </el-form-item>
                        <el-form-item label="密码" prop="password" v-if="!userParams.id">
                            <el-input placeholder="请输入用户密码" type="password" v-model="userParams.password"></el-input>
                        </el-form-item>
                        <el-form-item label="确认密码" prop="password2" v-if="!userParams.id">
                            <el-input placeholder="再次输入用户密码" type="password" v-model="userParams.password2"></el-input>
                        </el-form-item>
                    </el-form>
                    
                </template>
                <template #footer>
                    <div>
                        <el-button @click="cancel1">取消</el-button>
                        <el-button type="primary" @click="confirmClick">确定</el-button>
                    </div>
                </template>
            </el-drawer>


        </el-card>
    </div>
</template>

<style scoped lang="scss">
.form{
    display: flex;
    justify-content: space-between;
    align-items: center;
}
</style>